package com.andengine.editor.components;

import com.andengine.editor.components.CheckBoxList.Item;
import com.gooddies.swing.hList;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JCheckBox;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;

public class CheckBoxList<T> extends hList<Object> {

    public class Item {

        T obj;
        boolean checked;
    }

    public interface OnSelectionChange<T> {

        /**
         Method should return boolean value, that means - is it allowed to change the state of selection
         */
        public boolean change(T object,int index, boolean state);
    }

    private final JCheckBox checkboxEtalon = new JCheckBox();
    protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
    private OnSelectionChange selectionChangeEvent;

    @Override
    public synchronized void addMouseListener(MouseListener l) {
        getJList().addMouseListener(l);
    }

    
    
    public CheckBoxList() {
        setCellRenderer(new CellRenderer());
        getJList().addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                if (e.getX() < 20) {
                    int index = locationToIndex(e.getPoint());
                    if (index != -1) {
                        Item item = ((Item) getJList().getModel().getElementAt(index));
                        boolean newState = !item.checked;
                        repaint();
                        boolean isAllowChange = true;
                        if (selectionChangeEvent != null) {
                            isAllowChange = selectionChangeEvent.change(item.obj,index, newState);
                        }
                        if (isAllowChange) {
                            item.checked = newState;
                        }
                    }
                }
            }
        });

        getJList().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    }

    public void setSelectionChangeEvent(OnSelectionChange<T> event) {
        this.selectionChangeEvent = event;
    }

    public void addCheckBoxItem(T item) {
        Item i = new Item();
        i.checked = true;
        i.obj = item;
        super.addItem((Object) i);
    }

    public void addCheckBoxItem(T item, boolean status) {
        Item i = new Item();
        i.checked = status;
        i.obj = item;
        super.addItem((Object) i);
    }

    public void addCheckBoxItem(T item, int index) {
        Item i = new Item();
        i.checked = true;
        i.obj = item;
        super.addItem(i, index);
    }

    @Override
    public T getSelectedItem() {
        Item i = (Item) super.getSelectedItem();
        if (i == null) {
            return null;
        }
        return i.obj;
    }

    public boolean isItemSelected(int index) {
        Item i = (Item) super.getItem(index);
        if (i == null) {
            return false;
        }

        return i.checked;
    }

    @Override
    public T getItem(int index) {
        Item i = (Item) super.getItem(index);
        if (i == null) {
            return null;
        }
        return i.obj;
    }

    protected class CellRenderer implements ListCellRenderer {

        @Override
        public Component getListCellRendererComponent(
                JList list, Object value, int index,
                boolean isSelected, boolean cellHasFocus) {
            Item i = (Item) value;
            checkboxEtalon.setBackground(isSelected
                    ? getJList().getSelectionBackground() : CheckBoxList.this.getJList().getBackground());
            checkboxEtalon.setForeground(isSelected
                    ? getJList().getSelectionForeground() : getForeground());
            checkboxEtalon.setText(i.obj.toString());
            checkboxEtalon.setSelected(i.checked);
            checkboxEtalon.setEnabled(true);
            checkboxEtalon.setFont(getFont());
            checkboxEtalon.setFocusPainted(false);
            checkboxEtalon.setBorderPainted(true);
            checkboxEtalon.setBorder(isSelected ? UIManager.getBorder("List.focusCellHighlightBorder") : noFocusBorder);
            return checkboxEtalon;
        }
    }
}
